package com.ruicar.afs.cloud.product.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.common.core.log.annotation.SysLog;
import com.ruicar.afs.cloud.common.core.util.IResponse;
import com.ruicar.afs.cloud.product.condition.ProductAtomCondition;
import com.ruicar.afs.cloud.product.condition.ProductTemplateCondition;
import com.ruicar.afs.cloud.product.entity.ProductAtom;
import com.ruicar.afs.cloud.product.entity.ProductTemplate;
import com.ruicar.afs.cloud.product.entity.ProductTemplateAtom;
import com.ruicar.afs.cloud.product.enums.StatusEnum;
import com.ruicar.afs.cloud.product.service.ProductAtomService;
import com.ruicar.afs.cloud.product.service.ProductTemplateAtomService;
import com.ruicar.afs.cloud.product.service.ProductTemplateService;
import com.ruicar.afs.cloud.product.vo.ProductTemplateAtomVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author changyu.gui
 * @version 1.0
 * @date 2020/4/27 20:09
 */
@Slf4j
@RestController
@AllArgsConstructor
@Api("产品模板原子接口")
@RequestMapping("/productTemplateAtom")
public class ProductTemplateAtomController {

    private final ProductAtomService productAtomService;
    private final ProductTemplateAtomService productTemplateAtomService;
    private final ProductTemplateService productTemplateService;

    @RequestMapping(value = "/upTemplate", method = RequestMethod.POST)
    @ApiOperation(value = "上移模板")
    @SysLog("上移模板")
    @Transactional(rollbackFor = Exception.class)
    public IResponse<Boolean> upTemplate(@ModelAttribute ProductTemplateCondition productTemplateCondition) {
        ProductTemplateAtom productTemplateAtom = productTemplateAtomService.getById(productTemplateCondition.getId());
        Boolean flag = productTemplateAtomService.update(Wrappers.<ProductTemplateAtom>update().lambda().set(ProductTemplateAtom::getAtomSerialNumber, productTemplateAtom.getAtomSerialNumber())
                .eq(ProductTemplateAtom::getAtomSerialNumber, productTemplateAtom.getAtomSerialNumber() - 1)
                .eq(ProductTemplateAtom::getProductTemplateId, productTemplateAtom.getProductTemplateId())
        );
        if (!flag) {
            return IResponse.fail("不可下移");
        }
        productTemplateAtom.setAtomSerialNumber(productTemplateAtom.getAtomSerialNumber() - 1);
        productTemplateAtomService.updateById(productTemplateAtom);
        return new IResponse<Boolean>().setData(true).setMsg("上移模板成功");
    }

    @RequestMapping(value = "/downTemplate", method = RequestMethod.POST)
    @ApiOperation(value = "下移模板")
    @SysLog("下移模板")
    @Transactional(rollbackFor = Exception.class)
    public IResponse<Boolean> downTemplate(@ModelAttribute ProductTemplateCondition productTemplateCondition) {
        ProductTemplateAtom productTemplateAtom = productTemplateAtomService.getById(productTemplateCondition.getId());
        Boolean flag = productTemplateAtomService.update(Wrappers.<ProductTemplateAtom>update().lambda().set(ProductTemplateAtom::getAtomSerialNumber, productTemplateAtom.getAtomSerialNumber())
                .eq(ProductTemplateAtom::getAtomSerialNumber, productTemplateAtom.getAtomSerialNumber() + 1)
                .eq(ProductTemplateAtom::getProductTemplateId, productTemplateAtom.getProductTemplateId())
        );
        if (!flag) {
            return IResponse.fail("不可下移");
        }
        productTemplateAtom.setAtomSerialNumber(productTemplateAtom.getAtomSerialNumber() + 1);
        productTemplateAtomService.updateById(productTemplateAtom);
        return new IResponse<Boolean>().setData(true).setMsg("下移模板成功");
    }

    @RequestMapping(value = "/delById/{id}", method = RequestMethod.DELETE)
    @ApiOperation(value = "通过id删除")
    @Transactional
    @SysLog("通过id删除")
    public IResponse<Boolean> delById(@PathVariable String id) {
        ProductTemplateAtom productTemplateAtom = productTemplateAtomService.getById(id);
        if (productTemplateAtom == null)
            return new IResponse<Boolean>().setMsg("数据不存在");
        ProductAtom productAtom = productAtomService.getById(productTemplateAtom.getProductAtomId());
        if (productAtom != null && AfsEnumUtil.key(StatusEnum.YES).equals(productAtom.getAtomIsDefault())) {
            return IResponse.fail("产品默认原子不可删除！");
        }
        ProductTemplate productTemplate = productTemplateService.getById(productTemplateAtom.getProductTemplateId());
        if (AfsEnumUtil.key(StatusEnum.YES).equals(productTemplate.getIsEffective())) {
            productTemplateAtomService.saveTemplateInfo(productTemplate);
            productTemplateAtomService.remove(Wrappers.<ProductTemplateAtom>query().lambda()
                    .eq(ProductTemplateAtom::getProductAtomId, productTemplateAtom.getProductAtomId())
                    .eq(ProductTemplateAtom::getProductTemplateId, productTemplate.getId())
            );
        } else {
            int count = productTemplateAtomService.count(Wrappers.<ProductTemplateAtom>query().lambda()
                    .notIn(ProductTemplateAtom::getProductTemplateId, productTemplate.getId())
                    .eq(ProductTemplateAtom::getProductAtomId, productTemplateAtom.getProductAtomId())
            );
            if (count == 0) productAtomService.updateAtomIsReference(productAtom, AfsEnumUtil.key(StatusEnum.NO));
            productTemplateAtomService.removeById(id);
        }
        return IResponse.success(productTemplate);
    }

    @RequestMapping(value = "/getProductTemplateDetails", method = RequestMethod.GET)
    @ApiOperation(value = "获取产品模块原子信息")
    public IResponse<List<ProductTemplateAtomVo>> getProductTemplateDetails(@ModelAttribute ProductTemplateCondition productTemplateCondition) {
        IPage<List<ProductTemplateAtomVo>> list = productTemplateAtomService.getProductTemplateAtomVoList(new Page(productTemplateCondition.getPageNumber(), productTemplateCondition.getPageSize()), productTemplateCondition.getProductTemplateId());
        return IResponse.success(list);
    }

    @RequestMapping(value = "/editTemPlateAtom", method = RequestMethod.POST)
    @ApiOperation(value = "修改产品模板原子信息", notes = "需要通过id获取产品模板原子信息")
    @SysLog("修改产品模板原子信息")
    @Transactional(rollbackFor = Exception.class)
    public IResponse<Boolean> edit(@RequestBody ProductTemplateCondition productTemplateCondition) {
        ProductTemplateAtom productTemplateAtom = productTemplateAtomService.getById(productTemplateCondition.getId());
        if (productTemplateAtom == null)
            return IResponse.fail("模板产品默认原子不存在！");
        if (!productTemplateAtom.getIsMust().equals(productTemplateAtom.getIsMust()))
            return IResponse.success("修改成功");
        if (AfsEnumUtil.key(StatusEnum.YES).equals(productTemplateAtom.getIsMust())) {
            productTemplateAtom.setIsMust(AfsEnumUtil.key(StatusEnum.NO));
        } else {
            productTemplateAtom.setIsMust(AfsEnumUtil.key(StatusEnum.YES));
        }
        productTemplateAtomService.updateById(productTemplateAtom);
        return IResponse.success("修改成功");
    }

    @RequestMapping(value = "/saveTemplateAtom", method = RequestMethod.POST)
    @ApiOperation(value = "保存产品模板原子")
    @SysLog("保存产品模板原子")
    @Transactional(rollbackFor = Exception.class)
    public IResponse<Boolean> saveTemplateAtom(@ModelAttribute ProductAtomCondition atom) {

        //根据模板ID查询产品模板表
        ProductTemplate productTemplate = productTemplateService.getById(atom.getProductTemplateId());
        //根据模板是否有效，确定保存方法
        if (AfsEnumUtil.key(StatusEnum.YES).equals(productTemplate.getIsEffective())) {
            productTemplate = productTemplateAtomService.saveTemplateInfo(productTemplate);
            atom.setProductTemplateId(productTemplate.getId());
        }
        //查询排序最大的原子
        ProductTemplateAtom atom1Atom = productTemplateAtomService.getOne(Wrappers.<ProductTemplateAtom>query().lambda()
                .eq(ProductTemplateAtom::getProductTemplateId, productTemplate.getId())
                .orderByDesc(ProductTemplateAtom::getAtomSerialNumber), false);
        //得到默认排序值
        int atomSerialNumber = 0;
        if (atom1Atom != null) atomSerialNumber = atom1Atom.getAtomSerialNumber();
        //第一步根据id查询出产品原子数据
        List<ProductAtom> atomList = productAtomService.listByIds(Arrays.asList(atom.getIds()));
        //第二步根据id查询出产品模板里是否有该原子，有则移除产品原子
        productTemplateAtomService.list(Wrappers.<ProductTemplateAtom>query().lambda()
                .eq(ProductTemplateAtom::getProductTemplateId, atom.getProductTemplateId())
                .eq(ProductTemplateAtom::getProductAtomId, Arrays.asList(atom.getIds())))
                .forEach(productTemplateAtom -> {
                    atomList.forEach(productAtom -> {
                        if (productAtom.getId().equals(productTemplateAtom.getProductAtomId())) {
                            atomList.remove(productAtom);
                        }
                    });
                });
        //模板原子初始化
        List<ProductTemplateAtom> list = new ArrayList<>();
        //产品原子初始化
        List<ProductAtom> productAtomlist = new ArrayList<>();
        //第三步把需要保存产品原子数据，组装成产品模板原子数据，和移除产品原子状态为已被使用的数据
        for (ProductAtom productAtom : atomList) {
            //原子是否引用初始化
            productAtom.setAtomIsReference(AfsEnumUtil.key(StatusEnum.YES));
            productAtomlist.add(productAtom);
            //模板原子初始化
            ProductTemplateAtom productTemplateAtom = new ProductTemplateAtom(productTemplate.getId(), productAtom.getId(), productAtom.getAtomIsDefault(), atomSerialNumber);
            list.add(productTemplateAtom);
            //排序默认+1
            atomSerialNumber++;
        }
        //更新原子是否引用
        if (productAtomlist.size() > 0) productAtomService.updateBatchById(productAtomlist);
        //更新模板原子
        if (list.size() > 0) productTemplateAtomService.saveBatch(list);

        //保存默认原子
        atom.setAtomSerialNumber(atomSerialNumber);
        atom.setTemplateCategory(productTemplate.getTemplateCategory());
        productTemplateAtomService.saveProductTemplateAtomDefault(atom);
        return IResponse.success(productTemplate);
    }

    @RequestMapping(value = "/isNotMust", method = RequestMethod.POST)
    @ApiOperation(value = "设置不必填")
    @SysLog("设置不必填")
    @Transactional(rollbackFor = Exception.class)
    public IResponse<Boolean> isNotMust(@ModelAttribute ProductTemplateCondition productTemplateCondition) {
        List<ProductTemplateAtom> productTemplateAtomList = productTemplateAtomService.listByIds(Arrays.asList(productTemplateCondition.getIds()));
        List<Long> ids = new ArrayList<>();
        List<ProductTemplateAtom> list = new ArrayList<>();
        for (ProductTemplateAtom productTemplateAtom : productTemplateAtomList) {
            if (productTemplateAtom == null) return IResponse.fail("产品模板原子不存在！");
            if (!AfsEnumUtil.key(StatusEnum.NO).equals(productTemplateAtom.getIsMust())) {
                productTemplateAtom.setIsMust(AfsEnumUtil.key(StatusEnum.NO));
                ids.add(productTemplateAtom.getProductAtomId());
                list.add(productTemplateAtom);
            }
        }
        if (ids.size() > 0) {
            List<ProductAtom> listAtom = productAtomService.list(Wrappers.<ProductAtom>query().lambda().in(ProductAtom::getId, ids).eq(ProductAtom::getAtomIsDefault, AfsEnumUtil.key(StatusEnum.YES)));
            if (listAtom != null && listAtom.size() > 0) return IResponse.fail("产品默认原子不可修改！");
            if (list.size() > 0) productTemplateAtomService.updateBatchById(list);
        }
        return new IResponse<Boolean>().setData(true).setMsg("批量通过id设置数据不必填成功");
    }

    @RequestMapping(value = "/isMust", method = RequestMethod.POST)
    @ApiOperation(value = "设置必填")
    @SysLog("设置必填")
    @Transactional(rollbackFor = Exception.class)
    public IResponse<Boolean> isMust(@ModelAttribute ProductTemplateCondition productTemplateCondition) {
        List<ProductTemplateAtom> productTemplateAtomList = productTemplateAtomService.listByIds(Arrays.asList(productTemplateCondition.getIds()));
        List<Long> ids = new ArrayList<>();
        List<ProductTemplateAtom> list = new ArrayList<>();
        for (ProductTemplateAtom productTemplateAtom : productTemplateAtomList) {
            if (productTemplateAtom == null) return IResponse.fail("产品模板原子不存在！");
            if (!AfsEnumUtil.key(StatusEnum.YES).equals(productTemplateAtom.getIsMust())) {
                productTemplateAtom.setIsMust(AfsEnumUtil.key(StatusEnum.YES));
                ids.add(productTemplateAtom.getProductAtomId());
                list.add(productTemplateAtom);
            }
        }
        if (ids.size() > 0) {
            List<ProductAtom> listAtom = productAtomService.list(Wrappers.<ProductAtom>query().lambda().in(ProductAtom::getId, ids).eq(ProductAtom::getAtomIsDefault, AfsEnumUtil.key(StatusEnum.YES)));
            if (listAtom != null && listAtom.size() > 0) return IResponse.fail("产品默认原子不可修改！");
            if (list.size() > 0) productTemplateAtomService.updateBatchById(list);
        }
        return new IResponse<Boolean>().setData(true).setMsg("批量通过id设置数据必填成功");
    }


    @RequestMapping(value = "/removeAll", method = RequestMethod.POST)
    @ApiOperation(value = "删除原子")
    @Transactional(rollbackFor = Exception.class)
    public IResponse<Boolean> removeAll(@ModelAttribute ProductTemplateCondition productTemplateCondition) {

        //查询模板信息
        ProductTemplate productTemplate = productTemplateService.getById(productTemplateCondition.getId());
        //初始化模板原子信息
        List productAtomIdList = new ArrayList();
        for (Long id : productTemplateCondition.getIds()) {
            ProductTemplateAtom productTemplateAtom = productTemplateAtomService.getById(id);
            ProductAtom productAtom = productAtomService.getById(productTemplateAtom.getProductAtomId());
            //判断默认原子不可删除
            if (productAtom != null && AfsEnumUtil.key(StatusEnum.YES).equals(productAtom.getAtomIsDefault())) {
                return IResponse.fail("产品默认原子不可删除！");
            }
            productAtomIdList.add(productTemplateAtom.getProductAtomId());
        }
        //根据模板是否生效决定不同处理方式
        if (AfsEnumUtil.key(StatusEnum.YES).equals(productTemplate.getIsEffective())) {
            //模板生效则生成新的模板
            productTemplateAtomService.saveTemplateInfo(productTemplate);
        }
        //删除对应的原子
        productTemplateAtomService.removeAll(productTemplate.getId(), productAtomIdList);
        return IResponse.success(productTemplate);
    }

    @RequestMapping(value = "/moveTemplateAll", method = RequestMethod.POST)
    @ApiOperation(value = "移动选中模板")
    @Transactional(rollbackFor = Exception.class)
    public IResponse<Boolean> moveTemplateAll(@ModelAttribute ProductTemplateCondition productTemplateCondition) {
        //查询模板信息
        ProductTemplate productTemplate = productTemplateService.getById(productTemplateCondition.getId());
        productTemplateAtomService.moveTemplateAll(productTemplateCondition);
        return IResponse.success(productTemplate);
    }


}
